package com.hb.C_Lambda表达式和集合



fun main() {
   println("--------fold---------")
    val items = listOf(1, 2, 3, 4, 5)

    // Lambdas 表达式是花括号括起来的代码块。
    items.fold(0, {
        // 如果一个 lambda 表达式有参数，前面是参数，后跟“->”
            acc: Int, i: Int ->
        print("acc = $acc, i = $i, ")
        val result = acc + i
        println("result = $result")
        // lambda 表达式中的最后一个表达式是返回值：
        result
    })

    // lambda 表达式的参数类型是可选的，如果能够推断出来的话：
    val joinedToString = items.fold("Elements:", { acc, i -> acc + " " + i })

    // 函数引用也可以用于高阶函数调用：
    val product = items.fold(1, Int::times)
    println()

    println("joinedToString = $joinedToString")
    println("product = $product")
}

/**
 * 高阶函数与lambda
 * 一个方法或者一个函数接收的参数是一个函数或者返回值是一个函数这就是高阶函数
 *
 * lambda表达式的格式要求
 * 1. 一个lambda表达式总是被一对花括号所包围
 * 2. 其参数（如果有的话）位于 -> 之前（参数类型是可以省略的）
 * 3. 执行体位于 -> 之后
 *
 * 在kotlin中，如果一个函数的最后一个参数是个函数，那么可以将lambda表达式作为实参传递进去
 * 并且可以在调用时，方法圆括号外去使用
 *
 */

/**
 * fold
 * 它接受一个初始累积值与一个接合函数，并通过将当前累积值与每个集合元素连续接合起来代入累积值来构建返回值：

        fun <T, R> Collection<T>.fold(
        initial: R,
        combine: (acc: R, nextElement: T) -> R
        ): R {
        var accumulator: R = initial
        for (element: T in this) {
        accumulator = combine(accumulator, element)
        }
        return accumulator
        }


 * 在上述代码中，参数 combine 具有函数类型 (R, T) -> R，因此 fold 接受一个函数作为参数，
 * 该函数接受类型分别为 R 与 T 的两个参数并返回一个 R 类型的值。 在 for-循环内部调用该函数，
 * 然后将其返回值赋值给 accumulator。
 *
 * 为了调用 fold，需要传给它一个函数类型的实例作为参数，而在高阶函数调用处，（下文详述的）lambda 表达 式广泛用于此目的。
 * */